#include "sekai/ControlTrack.h"
#include <assert.h>

#if 1
//move this logic to sinsy
void ControlTrack::addNote(float start, float length, float f0) {
  if (time.size() == 0) {
    time.push_back(start);
    pitch.push_back(f0);
    interp.startPos = start;
    interp.endPos = start + length;
    time.push_back(start + 0.8 * length);
    pitch.push_back(f0);
  } else {
    time.push_back(start + 0.2 * length);
    pitch.push_back(f0);
    time.push_back(start + 0.5 * length);
    pitch.push_back(f0);
    time.push_back(start + 0.8 * length);
    pitch.push_back(f0);
    interp.endPos = start + length;
  }
  int count = time.size();
  fprintf(stderr,"ControlTrack::addNote() count=%i\n",count);
}
#endif



void ControlTrack::append(float delta)
{
  int count = time.size();
  float lastf0 = pitch[count - 1];
  pitch.push_back(lastf0);
  time.push_back(interp.endPos+delta);
  interp.endPos= interp.endPos+delta;
  count++;
}

void ControlTrack::addPoint(float pos,float f0)
{
    if(time.size() == 0)
        interp.startPos = pos;
    else
        interp.endPos= pos;
    
    if(time.size()==0 || pos>lastpos)
    {
        printf("addPoint %f %f\n",pos,lastpos);
        time.push_back(pos);
        pitch.push_back(f0);
        lastpos=pos;
    }
    
    
    
}

void ControlTrack::fix() {
  
  append(0.1);
  append(0.1); 
  append(0.1); 

  assert(time.size() == pitch.size());

  interp.acc = gsl_interp_accel_alloc();
  interp.cspline = gsl_spline_alloc(gsl_interp_cspline, time.size());
  gsl_spline_init(interp.cspline, time.data(), pitch.data(), time.size());
}

float ControlTrack::getF0atTime(float time) {
  if (time >= interp.startPos && time <= interp.endPos) {
    return gsl_spline_eval(interp.cspline, (double)time, interp.acc);
  }
  return 0.0;
}

float ControlTrack::getDynamicsAtTime(float time)
{
    for(const auto& d: dyn) {
        if(time>=d.start && time<d.end)
        {
            float tmp = (time - d.start) / (d.end - d.start);
            return d.dyn0 * (1 - tmp) + d.dyn1 * tmp;
        }
    }
    return 1.0;
}



float ControlTrack::getLength() { return interp.endPos; }
